package com.lhkj.ct.meta.modules.psychology.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.lhkj.ct.base.enums.DeleteStatus;
import com.lhkj.ct.base.model.dto.PageQuery;
import com.lhkj.ct.base.mybatis.core.metadata.SqlOrder;
import com.lhkj.ct.base.mybatis.extension.service.impl.IServiceImpl;
import com.lhkj.ct.base.utils.ShiroUtil;
import com.lhkj.ct.base.utils.Validate;
import com.lhkj.ct.base.utils.file.word.PoiWordUtils;
import com.lhkj.ct.meta.modules.psychology.mapper.ScaleReportMapper;
import com.lhkj.ct.meta.modules.psychology.model.entity.TblScaleReport;
import com.lhkj.ct.meta.modules.psychology.model.vo.EvaluationHistoryVo;
import com.lhkj.ct.meta.modules.psychology.model.vo.PersonalReportInfo;
import com.lhkj.ct.meta.modules.psychology.service.ScaleReportService;
import com.lhkj.ct.meta.modules.recycle.common.constant.RecycleType;
import com.lhkj.ct.meta.modules.recycle.entity.TblRecycleBin;
import com.lhkj.ct.meta.modules.recycle.service.RecycleBinService;
import com.lhkj.ct.meta.modules.report.BaseFactory;
import com.lhkj.ct.meta.modules.report.word.personal.PersonalReportHandle;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 测验报告 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2023-10-16
 */
@Service
public class ScaleReportServiceImpl extends IServiceImpl<ScaleReportMapper, TblScaleReport> implements ScaleReportService {

    @Resource
    private RecycleBinService recycleBinService;

    @Override
    public IPage<TblScaleReport> selectReportPage(TblScaleReport report, PageQuery pageQuery) {
        return getBaseMapper().selectReportPage(
                generatePage(pageQuery, SqlOrder.desc(TblScaleReport::getSubmissionTime, "t")),
                report,
                pageQuery);
    }

    @Override
    public IPage<TblScaleReport> selectReportPageByPatient(TblScaleReport report, PageQuery pageQuery) {
        report.setPatId(ShiroUtil.getAuthUserInfo().getUserId());
        return getBaseMapper().selectReportPageByPatient(
                generatePage(pageQuery, SqlOrder.desc(TblScaleReport::getSubmissionTime, "t")),
                report,
                pageQuery);
    }

    @Override
    public List<EvaluationHistoryVo> selectHistoriesByUser(String patId) {
        return getBaseMapper().selectHistoriesByUser(patId);
    }

    @Override
    public PersonalReportInfo getReportInfo(String reportId) {
        return getBaseMapper().getReportInfo(reportId);
    }

    @Override
    public boolean review(String rId) {
        TblScaleReport report = getBaseMapper().selectById(rId);
        Validate.isFalse(null == report || DeleteStatus.DELETED.equals(report.getDelFlag()), "报告不存在或已删除！");
        Validate.validState(0 == report.getReportStatus(), "报告已审核或已发布");
        return SqlHelper.retBool(getBaseMapper().update(null,
                new LambdaUpdateWrapper<TblScaleReport>()
                        .set(TblScaleReport::getReportStatus, 1)
                        .set(TblScaleReport::getReviewBy, ShiroUtil.getAuthUserInfo().getUserId())
                        .set(TblScaleReport::getReviewTime, LocalDateTime.now())
                        .eq(TblScaleReport::getId, rId)
        ));
    }

    @Override
    public int publish(List<String> ids) {
        return getBaseMapper().update(null,
                new LambdaUpdateWrapper<TblScaleReport>()
                        .set(TblScaleReport::getReportStatus, 2)
                        .in(TblScaleReport::getId, ids)
                        .eq(TblScaleReport::getReportStatus, 1)
                        .eq(TblScaleReport::getDelFlag, DeleteStatus.NORMAL)
        );
    }

    @Override
    public void exportWord(String rId) {
        PersonalReportInfo reportInfo = getReportInfo(rId);
        Validate.validState(reportInfo.getReportStatus() == 1 || reportInfo.getReportStatus() == 2, "报告未审核，无法导出！");
        XWPFDocument document = BaseFactory.getReport(new PersonalReportHandle(reportInfo.getLayout()), reportInfo);
        PoiWordUtils.wordDownload(document, reportInfo.getScaleName() + ".docx");
    }

    @Override
    public void exportPdf(String rId) {
        PersonalReportInfo reportInfo = getReportInfo(rId);
        XWPFDocument document = BaseFactory.getReport(new PersonalReportHandle(reportInfo.getLayout()), reportInfo);
        PoiWordUtils.wordToPdfDownload(document, reportInfo.getScaleName() + ".pdf");
    }

    @Override
    @SuppressWarnings("unchecked")
    public int removeByIds(Collection<? extends Serializable> idList) {
        return recycleBinService.logicDelete((List<String>)idList, this::logicDelete);
    }

    @Transactional
    public int logicDelete(String id) {
        TblScaleReport target = getBaseMapper().getReportWithScaleName(id);
        if (null == target) {
            return 0;
        }
        return recycleBinService.logicDeleteRealSource(
                getBaseMapper(),
                id,
                TblScaleReport::getId,
                TblScaleReport::getDelFlag,
                DeleteStatus.DELETED,
                TblRecycleBin.builder()
                        .sourceId(id)
                        .title(String.join("-", target.getPatName(), target.getScaleName()))
                        .sourceType(RecycleType.SCALE_REPORT).build());
    }
}
